[bits 32]
%define ERROR_CODE  nop
%define ZERO        push 0

; cite the interrupt handler array in C program
extern idt_table
  
; Macro Function
; ---------------------------------
; VECTOR
; ---------------------------------
; @brief
;   Define interrupt handler
; @params
;   %1 index of interrupt
;   %2 address of interrupt
; @return
;   none

%macro VECTOR 2
  section .text
  interrupt%1entry:
    %2    ; push error code or nop
    
    ;save context
    push ds
    push es
    push fs
    push gs
    pushad

    ;send EOI
    mov al,0x20
    out 0xa0,al
    out 0x20,al

    push %1			 ; 不管idt_table中的目标程序是否需要参数,都一律压入中断向量号,调试时很方便
    call [idt_table + %1*4]       ; 调用idt_table中的C版本中断处理函数
    jmp intr_exit

  section .data   ; store 4 bits interrupt_entry address
    dd interrupt%1entry
  %endmacro


; Function
; ---------------------------------
; intr_exit 
; ---------------------------------
; @brief:
;   Restore context information when exiting the interrupt handler
; @params:
;   none
; @return:
;   none
global intr_exit
intr_exit:	     
  ; 以下恢复上下文环境
   add esp, 4			   ; 跳过中断号
   popad
   pop gs
   pop fs
   pop es
   pop ds
   add esp, 4			   ; 跳过error_code
   iretd

; ---------------------------------
; syscall_handler
; ---------------------------------
; @brief:
;   System call interrupt handler, number 80
; @params:
;   eax: System call sub-function number
;   ebx: 1st integer argument passed to the function
;   ecx: 2nd integer argument passed to the function
;   edx: 3rd integer argument passed to the function
; @return:
;   Depends on the sub-function called, saved in eax
extern syscall_table
global syscall_handler
syscall_handler:
    ; Error code (not used in this handler)
    push 0
    
    ; Save context
    push ds
    push es
    push fs
    push gs
    pushad

    ; Interrupt vector number (not used in this handler)
    push 0x80
    
    ; Push arguments onto the stack
    push edx
    push ecx
    push ebx
    
    ; Call the appropriate system call function from the syscall_table
    call [syscall_table + eax*4]
    
    ; Adjust stack to clean up arguments
    add esp, 12

    ; Save return value to eax register in the stack
    mov [esp + 8*4], eax

    ; Jump to interrupt exit
    jmp intr_exit

; ----------------------------------------------
section .data
; global define interrupt entry table
global interrupt_entry_table
interrupt_entry_table:

VECTOR 0x00,ZERO
VECTOR 0x01,ZERO
VECTOR 0x02,ZERO
VECTOR 0x03,ZERO 
VECTOR 0x04,ZERO
VECTOR 0x05,ZERO
VECTOR 0x06,ZERO
VECTOR 0x07,ZERO 
VECTOR 0x08,ERROR_CODE
VECTOR 0x09,ZERO
VECTOR 0x0a,ERROR_CODE
VECTOR 0x0b,ERROR_CODE 
VECTOR 0x0c,ZERO
VECTOR 0x0d,ERROR_CODE
VECTOR 0x0e,ERROR_CODE
VECTOR 0x0f,ZERO 
VECTOR 0x10,ZERO
VECTOR 0x11,ERROR_CODE
VECTOR 0x12,ZERO
VECTOR 0x13,ZERO 
VECTOR 0x14,ZERO
VECTOR 0x15,ZERO
VECTOR 0x16,ZERO
VECTOR 0x17,ZERO 
VECTOR 0x18,ERROR_CODE
VECTOR 0x19,ZERO
VECTOR 0x1a,ERROR_CODE
VECTOR 0x1b,ERROR_CODE 
VECTOR 0x1c,ZERO
VECTOR 0x1d,ERROR_CODE
VECTOR 0x1e,ERROR_CODE
VECTOR 0x1f,ZERO 
VECTOR 0x20,ZERO					;时钟中断
VECTOR 0X21,ZERO					;键盘中断
VECTOR 0X22,ZERO					;级联
VECTOR 0X23,ZERO					;串口2
VECTOR 0X24,ZERO					;串口1
VECTOR 0X25,ZERO					;并口2
VECTOR 0X26,ZERO					;软盘
VECTOR 0X27,ZERO					;并口1
VECTOR 0X28,ZERO					;实时时钟
VECTOR 0X29,ZERO					;重定向
VECTOR 0X2A,ZERO					;保留
VECTOR 0x2B,ZERO					;保留
VECTOR 0x2C,ZERO					;ps/2 鼠标
VECTOR 0x2D,ZERO					;fpu 浮点单元异常
VECTOR 0x2E,ZERO					;硬盘
VECTOR 0x2F,ZERO					;保留

